from django.shortcuts import render,redirect
from django.http import JsonResponse,HttpResponse
from vote.models import Subject,Teacher,User
from vote.forms import LoginForm,RegisterForm
from vote.captcha import Captcha
import random
import xlwt
import json
import os
from io import BytesIO
from urllib.parse import quote


ALL_CHARS = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ'
def get_captcha_code(length=4):
    selected_chars = random.choices(ALL_CHARS, k=length)
    return ''.join(selected_chars)
def get_captcha(request):
    """获得验证码"""
    code = get_captcha_code()
    print(code)
    request.session['captcha_code'] = code
    image = Captcha.instance().generate(code)
    return HttpResponse(image, content_type='image/png')

def export_teachers_excel(request):
    # 创建工作簿
    wb = xlwt.Workbook()
    # 添加工作表
    sheet = wb.add_sheet('老师信息表')
    # 查询所有老师的信息已经优化
    queryset = Teacher.objects.all().select_related('subject')
    # 向Excel表单中写入表头
    colnames = ('姓名', '介绍', '好评数', '差评数', '学科')
    for index, name in enumerate(colnames):
        sheet.write(0, index, name)
    # 向单元格中写入老师的数据
    props = ('name', 'detail', 'good_count', 'bad_count', 'subject')
    for row, teacher in enumerate(queryset):
        for col, prop in enumerate(props):
            value = getattr(teacher, prop, '')
            if isinstance(value, Subject):
                value = value.name
            sheet.write(row + 1, col, value)
    # 保存Excel
    buffer = BytesIO()
    wb.save(buffer)
    # 将二进制数据写入响应的消息体中并设置MIME类型
    resp = HttpResponse(buffer.getvalue(), content_type='application/vnd.ms-excel')
    # 中文文件名需要处理成百分号编码
    filename = quote('老师.xls')
    # 通过响应头告知浏览器下载该文件以及对应的文件名
    resp['content-disposition'] = f'attachment; filename="{filename}"'
    return resp

def get_teachers_data(request):
    # 查询所有老师的信息已优化
    queryset = Teacher.objects.all().only('name', 'good_count', 'bad_count')
    # 用生成式将老师的名字放在一个列表中
    names = [teacher.name for teacher in queryset]
    # 用生成式将老师的好评数放在一个列表中
    good = [teacher.good_count for teacher in queryset]
    # 用生成式将老师的差评数放在一个列表中
    bad = [teacher.bad_count for teacher in queryset]
    # 返回JSON格式的数据
    return JsonResponse({'names': names, 'good': good, 'bad': bad})

def show_bar(request, no):
    """显示柱状图"""
    return render(request, f'bar{no}.html')

def show_subjects(request):
    """查看所有学科"""
    subjects = Subject.objects.all()
    return render(request, 'subject.html', {'subjects': subjects})
    
def show_teachers(request):
    """显示指定学科的老师"""
    try:
        sno = int(request.GET['sno'])
        subject = Subject.objects.get(no=sno)
        teachers = subject.teacher_set.all()
        return render(request, 'teachers.html', {'subject': subject, 'teachers': teachers})
    except (KeyError, ValueError, Subject.DoesNotExist):
        return redirect('/vote/')
        
def praise_or_criticize(request):
    """好评"""
    code, hint = 10002, '无效的老师编号'
    try:
        tno = int(request.GET['tno'])
        teacher = Teacher.objects.filter(no=tno).first()
        if teacher:
            if request.path.startswith('/vote/teachers/praise/'):
                teacher.good_count += 1
            else:
                teacher.bad_count += 1
            teacher.save()
            code, hint = 10001, '投票操作成功'
    except (KeyError, ValueError):
        pass
    return JsonResponse({'code': code, 'hint': hint})



def register(request):
    """注册"""
    page, hint = 'register.html', ''
    if request.method == 'POST':
        form = RegisterForm(request.POST)
        if form.is_valid():
            form.save()
            page = 'login.html'
            hint = '注册成功，请登录'
        else:
            hint = '请输入有效的注册信息'
    return render(request, page, {'hint': hint})

def login(request):
    """用户登录"""
    hint = ''
    backurl = request.GET.get('backurl', '/vote/')
    if request.method == 'POST':
        backurl = request.POST['backurl']
        form = LoginForm(request.POST)
        if form.is_valid():
            code_from_session = request.session.get('captcha_code')
            code_from_user = form.cleaned_data['code']
            if code_from_session.lower() == code_from_user.lower():
                username = form.cleaned_data['username']
                password = form.cleaned_data['password']
                user = User.objects.filter(
                    username=username, password=password).first()
                if user:
                    request.session['userid'] = user.no
                    request.session['username'] = user.username
                    return redirect(backurl)
                else:
                    hint = '用户名或密码错误'
            else:
                hint = '请输入正确的验证码'
        else:
            hint = '请输入有效的登录信息'
    return render(request, 'login.html', {'hint': hint, 'backurl': backurl})


def logout(request):
    """注销"""
    request.session.flush()
    return redirect('/vote/')